import { TrackOpTypes } from "../utils";
import { activeEffect, depsMap } from "./effect";

/** 是否需要依赖收集 */
export let shouldTrack = true;

/**
 * 暂停依赖收集
 */
export const pauseTracking = () => {
  shouldTrack = false;
};

/**
 * 恢复依赖收集
 */
export const resumeTracking = () => {
  shouldTrack = true;
};

/**
 * 收集器
 * @param target 目标对象
 * @param type 收集的类型
 * @param key 属性名
 */
const track = (target: object, type: string, key?: string | symbol) => {
  // 如果不需要依赖收集，直接return
  if (!shouldTrack) return;

  if (type === TrackOpTypes.ITERATE) {
    // 说明是遍历操作
    // 此时没有第三个参数 key
    console.log(`收集器：代理对象${type}操作被拦截`);
    return;
  }

  // 建立依赖关系
  if (activeEffect) {
    let deps = depsMap.get(key!); // 根据key获取函数集合
    if (!deps) {
      // 没有集合就new一个
      deps = new Set();
      depsMap.set(key!, deps);
    }

    deps.add(activeEffect); // 将这个新的函数activeEffect添加到集合中
    activeEffect.deps.add(key!); // 这个key与这个activeEffect（/environment）关联了，后续activeEffect（/environment）被重新执行时，会清空所有关联
  }
  console.log(
    `收集器：属性${String(key)}和被监控的函数的集合：`,
    depsMap.get(key!)
  );
};

export default track;
